#include "Mage.h"

#include "ListeSorts.h"

using namespace std;
using namespace boost::assign;

const unsigned int Mage::nbr_comp = 31;

const unsigned int Mage::nbr_restric = 19;

const vector<ListComp> Mage::Comp = list_of
  (ListComp("Abjuration"                       ,  5))
  (ListComp("Alt\\'eration"                    ,  5))
  (ListComp("Conjuration\\ -\\ Convocation"    ,  5))
  (ListComp("Divination"                       ,  5))
  (ListComp("Enchantement\\ -\\ Charme"        ,  5))
  (ListComp("Illusion\\ -\\ Fantasme"          ,  5))
  (ListComp("Invocation\\ -\\ Evocation"       ,  5))
  (ListComp("N\\'ecromancie"                   ,  5))
  (ListComp("Armes de roublard / prêtre"       , 10))
  (ListComp("Compétences de prêtre"            ,  5))
  (ListComp("Compétences de combattant"        ,  5))
  (ListComp("Compétences de roublard"          ,  5))
  (ListComp("Coriace"                          ,  5))
  (ListComp("Dés de vie à 1d6"                 , 10))
  (ListComp("Dés de vie à 1d8"                 , 20))
  (ListComp("Détection de la magie"            , 10))
  (ListComp("Dissipation de la magie (1x/j)"   , 10))
  (ListComp("Dissipation de la magie (3x/j)"   , 15))
  (ListComp("Durée de sorts acrue (1 école)"   , 10))
  (ListComp("Durée de sorts acrue"             , 15))
  (ListComp("Incantation rapide"               ,  5))
  (ListComp("Lecture de la magie"              , 10))
  (ListComp("Mage combattant"                  , 10))
  (ListComp("Mage en armure"                   , 15))
  (ListComp("Magicien-prêtre (maj)"            , 15, 100, &Spheres))
  (ListComp("Magicien-prêtre (min)"            , 10, 100, &Spheres))
  (ListComp("Résistance aux charmes et sommeil",  5))
  (ListComp("Sélection d'armes étendue"        , 15))
  (ListComp("Sélection d'armes de prêtres"     , 10))
  (ListComp("Sélection d'armes de voleurs"     , 10))
  (ListComp("Sort automatique"                 ,  5))
  (ListComp("Spécialisation"                   , 15))
  (ListComp("Talents de voleur"                ,  5, 200, &TalVol));

const vector<ListComp> Mage::Restric = list_of
  (ListComp("Choix des armes restreint (déf ok)"          ,  3))
  (ListComp("Choix des armes restreint"                   ,  5))
  (ListComp("Comportement / tabou"                        ,  2))
  (ListComp("Cond. extérieures quotidiennes"              , 20))
  (ListComp("Cond. extérieures communes"                  , 15))
  (ListComp("Cond. extérieures rares"                     , 10))
  (ListComp("Cond. extérieures spécifiques"               ,  5))
  (ListComp("Dés de vie à 1d3"                            , 10))
  (ListComp("Difficultés de mémorisation"                 ,  5))
  (ListComp("Lim : potions, huiles et parchemins"         ,  5))
  (ListComp("Lim : anneau, de bâton, bâtonnet et baguette",  5))
  (ListComp("Lim : armes et armures magiques"             ,  5))
  (ListComp("Manque de discrétion"                        ,  5))
  (ListComp("Nombre de sorts réduit"                      ,  7))
  (ListComp("Progression ralentie"                        , 15))
  (ListComp("Sorts dangereux"                             , 10))
  (ListComp("Talisman"                                    ,  8))
  (ListComp("Temps d'incantation alongé (+3)"             ,  2))
  (ListComp("Temps d'incantation alongé (unité)"          ,  5));

//
// Pour les talents de voleur, il faut utiliser la Table 19 de la 
// page 630 du gros pdf.
//

const vector< ListComp > Mage::Spheres = list_of
  (ListComp("G\\'en\\'erale"))
  (ListComp("Animale"       ))
  (ListComp("Astrale"       ))
  (ListComp("Chaos"         ))
  (ListComp("Charme"        ))
  (ListComp("Climat"        ))
  (ListComp("Combat"        ))
  (ListComp("Conjuration"   ))
  (ListComp("Cr\\'eation"   ))
  (ListComp("Divination"    ))
  (ListComp("Air"           ))
  (ListComp("Eau"           ))
  (ListComp("Feu"           ))
  (ListComp("Terre"         ))
  (ListComp("Garde"         ))
  (ListComp("Guerre"        ))
  (ListComp("Loi"           ))
  (ListComp("N\\'ecromancie"))
  (ListComp("Nombres"       ))
  (ListComp("Pens\\'ee"     ))
  (ListComp("Protection"    ))
  (ListComp("Soin"          ))
  (ListComp("Soleil"        ))
  (ListComp("Temps"         ))
  (ListComp("V\\'eg\\'etale"))
  (ListComp("Vigilance"     ))
  (ListComp("Voyageur"      ));

const vector< ListComp > Mage::TalVol = list_of
  (ListComp("Attaque sournoise"                 ,  5, Basique))
  (ListComp("Corruption"                        ,  5, Pourcentage))
  (ListComp("Crocheter les serrures"            ,  5, Pourcentage))
  (ListComp("Déplacement silencieux"            ,  5, Pourcentage))
  (ListComp("Détection des bruits"              ,  5, Pourcentage))
  (ListComp("Détection de la magie"             ,  5, Pourcentage))
  (ListComp("Détection des illusions"           ,  5, Pourcentage))
  (ListComp("Esquive"                           ,  5))
  (ListComp("Evasion"                           ,  5, Pourcentage))
  (ListComp("Grimper"                           ,  5, Pourcentage))
  (ListComp("Jargon des voleurs"                ,  5))
  (ListComp("Lire des langues inconnues"        ,  5, Pourcentage))
  (ListComp("Percer un tunnel"                  ,  5, Pourcentage))
  (ListComp("Se cacher dans l'ombre"            ,  5, Pourcentage))
  (ListComp("Trouver et désamorcer les pièges"  ,  5, Pourcentage))
  (ListComp("Vol à la tire"                     ,  5, Pourcentage));

const vector< Prerequis > Mage::Limites = list_of
  (Prerequis(3, 9));

const set< string > Mage::RacesAdmises = list_of
  ( "Humain" ) ( "Demi-Elfe" ) ( "Elfe" );

/** Constructeur usuel.
 * Permet la construction d'un mage de A à Z, càd on détermine ici
 * les restrictions, puis les compétences.
 * @param xp le nombre de pts d'expérience du Mage.
 * @param trait les traits du Mage, le 7ème contient le score de
 * force exceptionnel, fixé à 0 si non applicable.
 * @param PP nombre de points de personnage (PP) à disposition pour la
 * céation du Mage.
 * @param race nom de la race du personnage.
 */
Mage::Mage(unsigned int xp, unsigned int trait[7], unsigned int PP,
	   const string& race)
  : Classe(xp, trait, Magiciens, race)
{
  Type_classe = "Mage";
  PP += 40;

  ptrComp         = &Comp;
  ptrRes          = &Restric;
  ptrNbrComp      = &nbr_comp;
  ptrNbrRes       = &nbr_restric;
  ptrTraitsRequis = &Limites;
  ptrRacesAdmises = &RacesAdmises;

  blank() << setfill('*') << setw(56) << '*' << endreq;
  blank() << "Création d'un mage" << endreq << endl;

  construitClasse( PP );

  blank() << endl << setfill('*') << setw(56) << '*' << endreq;
  calculNiveau();
  calculNivMag();
}

/** Constructeur simplifié.
 * Permet de construire un Mage lors de la lecture d'un ficier xml.
 * @param xp le nombre de pts d'expérience du Mage.
 * @param trait les traits du Mage, le 7ème contient le score de
 * force exceptionnel, fixé à 0 si non applicable.
 * @param race nom de la race du personnage.
 */
Mage::Mage(unsigned int xp, unsigned int trait[7], const string& race)
  : Classe(xp, trait, Magiciens, race)
{
  Type_classe = "Mage";

  ptrComp         = &Comp;
  ptrRes          = &Restric;
  ptrNbrComp      = &nbr_comp;
  ptrNbrRes       = &nbr_restric;
  ptrTraitsRequis = &Limites;
  ptrRacesAdmises = &RacesAdmises;

  calculNiveau();
  calculNivMag();
}

/** Constructeur pour le mode graphique.
 * Permet de construire une instance de Mage avec le contenu
 * minimal, le nombre de points d'expériences et les capacités étant
 * déterminées après la déclaration.
 *
 * @param trait les traits du Mage, le 7ème contient le score de
 * force exceptionnel, fixé à 0 si non applicable.
 * @param UI contrôle, est présent pour des raisons historiques.
 * @param race nom de la race du personnage.
 */
Mage::Mage(unsigned int trait[7], const bool& UI, const string& race)
  : Classe(0, trait, Magiciens, race)
{
  Type_classe = "Mage";

  ptrComp         = &Comp;
  ptrRes          = &Restric;
  ptrNbrComp      = &nbr_comp;
  ptrNbrRes       = &nbr_restric;
  ptrTraitsRequis = &Limites;
  ptrRacesAdmises = &RacesAdmises;

  if (!UI)
    {
      error() << "Création du personnage impossible" << endreq;
      exit(1);
    }
}

Mage::~Mage()
{}

void Mage::calculNiveau()
{
  if (XP < 60000)
    {
      unsigned int i;
      for (i = 0; i < 5; i++)
	{
	  if (XP < (unsigned int) 2500 * puissance(2, i))
	    break;
	}
      Niveau = i+1;
    }
  else if (XP < 90000)
    Niveau = 7;
  else if (XP < 135000)
    Niveau = 8;
  else if (XP < 250000)
    Niveau = 9;
  else if (XP < 375000)
    Niveau = 10;
  else if (XP < 750000)
    Niveau = 11;
  else
      Niveau = (XP - 750000) / 375000 + 12;
}

// /**
//  * L'affichage des restrictions est précédé de l'affichage du numéro de
//  * cette restriction...
//  */
// void Mage::afficher_stats(ostream& os)
// {
//   os << "Mage" << endreq;
//   for (unsigned int i(0); i<6; i++)
//     os << Caracteristiques[i] << ' ' << Traits[i] << endreq;
//   for (unsigned int i(0); i < Comp_classe.size(); i++)
//     {
//       if (Comp_classe[i] >= nbr_comp)
// 	{
// 	  //os << Comp_classe[i] << endreq;
// 	  os << Restric[Comp_classe[i]-20].Comp << endreq;
// 	}
//       else
// 	os << Comp[Comp_classe[i]].Comp << endreq;
//     }
// }

// void Mage::appliquerModif(const string& type)
// {}

// void Mage::augmenterTalents(const unsigned int& bonus, const bool& lvl_up)
// {}

void Mage::getJS(unsigned int *tab) const
{
  *(tab + 0) = 14; // Paralysie, Poison ou Mort magique
  *(tab + 1) = 11; // Bâton, batonnet baguette
  *(tab + 2) = 13; // Pétrification ou Métamorphose
  *(tab + 3) = 15; // Souffles
  *(tab + 4) = 12; // Sorts
  
  unsigned int cat;
  if (Niveau <= 5)
    cat = 0;
  else  if (Niveau <= 10)
    cat = 1;
  else  if (Niveau <= 15)
    cat = 2;
  else  if (Niveau <= 20)
    cat = 3;
  else
    cat = 4;

  *(tab + 0) -= cat;
  *(tab + 1) -= 2 * cat;
  *(tab + 2) -= 2 * cat;
  *(tab + 3) -= 2 * cat;
  *(tab + 4) -= 2 * cat;
}

// string Mage::getCompetence(const unsigned int& i) const
// {
//   Debug::empileNiveau( &elementaire );
//   //DebugLevelType etat_precedent(dout.getLevel());
//   //dout.setLevel(elementaire);
//   debug() <<  i << "-ème compétence => Compétence " << getComp(i)
// 	      << endreq;
//   if (getComp(i) < nbr_comp)
//     {
//       debug() << "=> compétence" << endreq;
//       Debug::depileNiveau();//dout.setLevel(etat_precedent);
//       return Comp[getComp(i)].Comp;
//     }
//   else
//     {
//       debug() << "=> restriction" << endreq;
//       Debug::depileNiveau();//dout.setLevel(etat_precedent);
//       return Restric[getComp(i)-nbr_comp].Comp;
//     }
// }

unsigned int Mage::calculeTAc0() const
{
  unsigned int mod_niveau((Niveau - 1) / 3);

  return 20 - mod_niveau;
}

void Mage::calculNivMag()
{
  if (Niveau < 11)
    Niveau_mag = (Niveau + 1) / 2;
  else if (Niveau == 11)
    Niveau_mag = 5;
  else if (Niveau < 20)
    Niveau_mag = Niveau / 2;
  else
    Niveau_mag = 9;
}

/**
 * Il faut ici regarder dans Cl_sorts pour savoir quels sont les sorts
 * contenus dans le Livre de Sorts du magicien.
 * 
 * Le tri se fait d'abord par Ecole, puis par Niveau et ensuite dans l'ordre
 * alphabétique.
 *
 * La variable Classe::fonction permet d'afficher :\n
 * - \e FUNC  début et fin de l'exécution de la méthode.\n
 * - \e DEBUG écrasement du fichier, nombre de sorts, sort courant
 */
void Mage::ecrireSorts(const string& nom_fichier, const bool& ecrase) const
{
  Debug::empileNiveau( &fonction );
  func() << "Mage::ecrireSorts -> début" << endreq;

  ofstream sortie;
  if (ecrase)
    {
      debug() << "Ecrasement du fichier " << nom_fichier << endreq;
      sortie.open(nom_fichier.c_str());
    }
  else
    {
      sortie.open(nom_fichier.c_str(), ios::app);
      sortie << "\\newpage" << endl;
    }

  sortie << "\\section*{Livre de sorts - Mage}" << endl;

  unsigned int *vec = new unsigned int[Niveau_mag];

  nbrSort(vec, Niveau_mag);
  
  sortie << "\\begin{center}" << endl 
	 << "\\begin{tabular*}{10cm}{@{\\extracolsep{\\fill}} l r}"
	 << endl << "\\multicolumn{2}{c}{Nombre de sorts par jour} \\\\"
	 << "\\hline \\\\ \\vspace{1mm}" << endl;
  for (unsigned int i(0); i < Niveau_mag; i++)
    sortie << "Niveau " << i+1 << " & " << vec[i] << " \\\\" << endl;
  sortie << "\\end{tabular*}" << endl << "\\end{center}" << endl;

  unsigned int taille(getCombienSorts()), i, courant(10), niv_courant(10);
  string nom_ecoles[8] = {
    "Abjuration", "Alt\\'eration", "Conjuration - Convocation",
    "Divination","Enchantement - Charme", "Illusion - Fantasme",
    "Invocation - Evocation", "N\\'ecromancie"};

  debug() << "nbr de sorts = " << taille << endreq;

  for(i = 0; i < taille; i++)
    {
      debug() << "Sort courant " << Cl_sorts[i] << endreq;
      if (Cl_sorts[i].getEcole() != courant)
	{
	  courant = Cl_sorts[i].getEcole();
	  niv_courant = Cl_sorts[i].getNiveau();
	  // courant garde en mémoire l'école courante
	  // niv_courant garde en mémoire le niveau courant
	  if (courant == 20)
	    sortie << "\\subsection*{Magie universelle}" << endl;
	  else
	    sortie << "\\subsection*{" << afficheAccent(nom_ecoles[courant])
		   << "}" << endl;
	  sortie << "\\subsubsection*{Niveau " << niv_courant << "}" << endl;
	}
      if (Cl_sorts[i].getNiveau() != niv_courant)
	{
	  niv_courant = Cl_sorts[i].getNiveau();
	  sortie << "\\subsubsection*{Niveau " << niv_courant << "}" << endl;
	}
      if (courant == 20)
      sortie << "\\input{../../Sorts-mage/Universelle" << "/sort_"
	     << niv_courant << "_" << Cl_sorts[i].getNumero() << ".inc.tex}"
	     << endl;
      else
	sortie << "\\input{../../Sorts-mage/"
	       << supprimeAccents(nom_ecoles[courant]) << "/sort_"
	       << niv_courant << "_" << Cl_sorts[i].getNumero()
	       << ".inc.tex}" << endl;
    }

  // Il faut ajouter encore l'éventuelle sphère de mage.
  vector< unsigned int >::const_iterator Maj, Min,
    Debut( Comp_classe.begin() ),Fin( Comp_classe.end() );
  Min = find( Debut, Fin, 25 );
  Maj = find( Debut, Fin, 24 );
  // Min et Maj sont utilisés pour savoir quelle est la sphère, en faisant ++
  // on tombe dessus
  if ( Maj != Fin )
    {
      // Alors on a une sphère majeure
    }
  else if ( Min != Fin )
    {
      // Alors on a une sphère mineure
    }

  sortie.close();
  func() << "Mage::ecrireSorts -> fin" << endreq;
  Debug::depileNiveau();//dout.setLevel(etat_precedent);
}

void Mage::nbrSort(unsigned int sorts[], const unsigned int& taille) const
{
  Debug::empileNiveau( &fonction );
  //DebugLevelType etat_precedent(dout.getLevel());
  //dout.setLevel(fonction);
  func() << "Mage::nbrSort -> début" << endreq;
  unsigned int i;
  unsigned int tmp[9];
  func() << "Niveau de magie = " << taille << endreq;

  for (i = 0; i < taille; i++)
    tmp[i] = 0;

  switch(Niveau)
    {
    case 1:
      tmp[0] = 1;
      break;
    case 2:
      tmp[0] = 2;
      break;
    case 3:
      tmp[0] = 2;
      tmp[1] = 1;
      break;
    case 4:
      tmp[0] = 3;
      tmp[1] = 2;
      break;
    case 5:
      tmp[0] = 4;
      tmp[1] = 2;
      tmp[2] = 1;
      break;
    case 6:
      tmp[0] = 4;
      tmp[1] = 2;
      tmp[2] = 2;
      break;
    case 7:
      tmp[0] = 4;
      tmp[1] = 3;
      tmp[2] = 2;
      tmp[3] = 1;
      break;
    case 8:
      tmp[0] = 4;
      tmp[1] = 3;
      tmp[2] = 3;
      tmp[3] = 2;
      break;
    case 9:
      tmp[0] = 4;
      tmp[1] = 3;
      tmp[2] = 3;
      tmp[3] = 2;
      tmp[4] = 1;
      break;
    case 10:
      tmp[0] = 4;
      tmp[1] = 4;
      tmp[2] = 3;
      tmp[3] = 2;
      tmp[4] = 2;
      break;
    case 11:
      tmp[0] = 4;
      tmp[1] = 4;
      tmp[2] = 4;
      tmp[3] = 3;
      tmp[4] = 3;
      break;
    case 12:
      tmp[0] = 4;
      tmp[1] = 4;
      tmp[2] = 4;
      tmp[3] = 4;
      tmp[4] = 4;
      tmp[5] = 1;
      break;
    case 13:
      tmp[0] = 5;
      tmp[1] = 5;
      tmp[2] = 5;
      tmp[3] = 4;
      tmp[4] = 4;
      tmp[5] = 2;
      break;
    case 14:
      tmp[0] = 5;
      tmp[1] = 5;
      tmp[2] = 5;
      tmp[3] = 4;
      tmp[4] = 4;
      tmp[5] = 2;
      tmp[6] = 1;
      break;
    case 15:
      tmp[0] = 5;
      tmp[1] = 5;
      tmp[2] = 5;
      tmp[3] = 5;
      tmp[4] = 5;
      tmp[5] = 2;
      tmp[6] = 1;
      break;
    case 16:
      tmp[0] = 5;
      tmp[1] = 5;
      tmp[2] = 5;
      tmp[3] = 5;
      tmp[4] = 5;
      tmp[5] = 3;
      tmp[6] = 2;
      tmp[7] = 1;
      break;
    case 17:
      tmp[0] = 5;
      tmp[1] = 5;
      tmp[2] = 5;
      tmp[3] = 5;
      tmp[4] = 5;
      tmp[5] = 3;
      tmp[6] = 3;
      tmp[7] = 2;
      break;
    case 18:
      tmp[0] = 5;
      tmp[1] = 5;
      tmp[2] = 5;
      tmp[3] = 5;
      tmp[4] = 5;
      tmp[5] = 3;
      tmp[6] = 3;
      tmp[7] = 2;
      tmp[8] = 1;
      break;
    case 19:
      tmp[0] = 5;
      tmp[1] = 5;
      tmp[2] = 5;
      tmp[3] = 5;
      tmp[4] = 5;
      tmp[5] = 3;
      tmp[6] = 3;
      tmp[7] = 3;
      tmp[8] = 1;
      break;
    default:
      tmp[0] = 5;
      tmp[1] = 5;
      tmp[2] = 5;
      tmp[3] = 5;
      tmp[4] = 5;
      tmp[5] = 4;
      tmp[6] = 3;
      tmp[7] = 3;
      tmp[8] = 2;
      break;
    }

  for (i = 0; i < Niveau_mag; i++)
    sorts[i] = tmp[i];

  func() << "Mage::nbrSort -> fin" << endreq;
  Debug::depileNiveau();//dout.setLevel(etat_precedent);
}

/**
 *
 * Permet de gérer l'ajout de sorts au livre du magicien
 *
 * La variable Classe::fonction permet d'afficher
 *
 * FUNC  : les messages de début - fin de la méthode
 *
 * LFUNC : les écoles auxquelles le Mage a accès
 *
 * DEBUG : numéro du dernier sort, sort écrit, sorts triés
 */
void Mage::ajoutSorts()
{
  Debug::empileNiveau( &fonction );
  //DebugLevelType etat_precedent(dout.getLevel());
  //dout.setLevel(fonction);
  func() << "Mage::ajoutSorts -> début" << endreq;

  bool ecoles[9] = {false, false, false, false, false, false, false, false};
  unsigned int taille(getCombien()), i;
  bool sauter( false );

  for (i = 0; i < taille; i++)
    {
      if (Comp_classe[i] < 8)
	{
	  ecoles[Comp_classe[i]] = true;
	  lfunc() << getCompetence(i, sauter) << " oui" << endreq;
	}
    }

  unsigned int nbr, dernier;
  string ecole;

  // On ajoute l'école de magie universelle
  blank() << "Magie universelle" << endreq;
  for (i = 1; i <= Niveau_mag; i++)
    {
      blank() << "Niveau " << i << " :" << endreq;
      dernier = afficheSorts(20, i);

      debug() << "dernier = " << dernier << endreq;

      if (dernier > 0)
	{
	  blank() << setw(2) << dernier + 1 << " Aucun" << endreq;
	  do
	    {
	      nbr = demanderUnsignedBorne("Entrer nouveau sort : ", 1,
					    dernier + 1);
	      if (nbr != dernier + 1)
		{
		  debug() << "Ajout du sort " << Sort(20, i, nbr - 1)
			      << endreq;
		  Cl_sorts.push_back(Sort(20, i, nbr - 1));
		}
	    }
	  while(nbr != dernier + 1);
	}
    }

  for (i = 0; i < 8; i++)
    {
      if (!ecoles[i])
	continue;
      blank() << getCompetence(i, sauter) << endreq;
      for (unsigned int j(1); j <= Niveau_mag; j++)
	{
	  blank() << "Niveau " << j << " :" << endreq;
	  dernier = afficheSorts(i, j);

	  debug() << "dernier = " << dernier << endreq;
	
	  if (dernier > 0)
	    {
	      blank() << setw(2) << dernier + 1 << " Aucun" << endreq;
	      do
		{
		  nbr = demanderUnsignedBorne("Entrer nouveau sort : ", 1,
						dernier + 1);
		  if (nbr != dernier + 1)
		    {
		      debug() << "Ajout du sort " << Sort(i, j, nbr - 1)
				  << endreq;
		      Cl_sorts.push_back(Sort(i, j, nbr - 1));
		    }
		}
	      while(nbr != dernier + 1);
	    }
	}
    }

  vector<Sort>::iterator Begin, End, it;
  Begin = Cl_sorts.begin();
  End   = Cl_sorts.end();

  for (i = 0; i < Cl_sorts.size(); i++)
    debug() << Cl_sorts[i] << endreq;

  debug() << "Tri effectué" << endreq;

  sort(Begin, End);

  unique( Begin, End );
  // for (it = ++Begin; it != End; it++)
  //   {
  //     if (*it == *(it - 1))
  // 	{
  // 	  lfunc() << "Même sort!" << endreq;
  // 	  Cl_sorts.erase(it);
  // 	}
  //   }

  for (i = 0; i < Cl_sorts.size(); i++)
    debug() << Cl_sorts[i] << endreq;

  func() << "Mage::ajoutSorts -> fin" << endreq;
  Debug::depileNiveau();//dout.setLevel(etat_precedent);
}

/**
 * Permet de gérer les compétences martiales, càd lesquelles sont
 * accessibles à quel coût.
 *
 * Un Mage peut prendre un arme réservée au Mage pour 3 pp, ou une
 * arme de Clerc ou de Voleur pour 5 pp et enfin une arme de Guerrier
 * pour 6 pp.
 *
 * Si le Mage a pris une compétence comme "Sélection d'armes étendue",
 * alors ces coûts sont changés automatiquement ici.
 */
void Mage::getPrixAcces(map<string, unsigned int>*& Map) const
{
  Debug::empileNiveau( &fonction );
  func() << "Mage::getPrixAcces -> début" << endreq;

  map<string, unsigned int>::const_iterator mapIt, mapBegin(Map -> begin()),
    mapEnd(Map -> end());

  vector< unsigned int >::const_iterator it, End( Comp_classe . end() );

  unsigned int prixGuerrier( 6 ), prixClerc( 5 ), prixVoleur( 5 );

  for (it = Comp_classe . begin(); it != End; it++)
    {
      switch( *it )
	{
	case 26:
	  prixGuerrier = 3;
	  break;
	case 27:
	  prixClerc = 3;
	  break;
	case 28:
	  prixVoleur = 3;
	}
    }

  for (mapIt = mapBegin; mapIt != mapEnd; mapIt++)
      lfunc() << mapIt -> first << endreq;

  Map -> operator[]("Mage")     = 3;
  mapIt = Map -> find("Clerc");
  if ((mapIt != mapEnd && mapIt -> second > 5) || mapIt == mapEnd)
    Map -> operator[]("Clerc")    = prixClerc;
  mapIt = Map -> find("Voleur");
  if ((mapIt != mapEnd && mapIt -> second > 5) || mapIt == mapEnd)
    Map -> operator[]("Voleur")   = prixVoleur;
  mapIt = Map -> find("Guerrier");
  if ((mapIt != mapEnd && mapIt -> second > 6) || mapIt == mapEnd)
    Map -> operator[]("Guerrier") = prixGuerrier;
  
  func() << "Mage::getPrixAcces -> fin" << endreq;
  Debug::depileNiveau();
}

string Mage::getScoreAdditionnel(const unsigned int& i) const
{
  Debug::empileNiveau( &fonction );
  func() << "Mage::getScoreAdditionnel -> début" << endreq;
  
  string resultat( "" );

  if ( i >= 200 && i < 300 )
    {
       if ( TalVol[ i - 200 ].Comp == "Attaque sournoise" )
	 {
	   switch( Niveau )
	     {
	     case 1:
	     case 2:
	     case 3:
	     case 4:
	       resultat = "dégâts x2";
	       break;
	     case 5:
	     case 6:
	     case 7:
	     case 8:
	       resultat = "dégâts x3";
	       break;
	     case 9:
	     case 10:
	     case 11:
	     case 12:
	       resultat = "dégâts x4";
	       break;
	     default:
	       resultat = "dégâts x5";
	     }
	 }
       else if ( TalVol[ i - 200 ].AutreScore == Pourcentage )
	 {
	   vector< unsigned int > *ptrComp;
	   vector< int > *ptrBonus;
	   obtenirScoresBase( Niveau, ptrComp );
	   determinerScoresAjustes( Type_race, Traits[1], ptrBonus );

	   // faire une map avec le matching et ensuite appliquer les
	   // ajustements de ptrBonus, et ensuite on peut écrire le tout
	 }
    }
  
  func() << "Voleur::getScoreAdditionnel -> fin" << endreq;
  Debug::depileNiveau();

  return resultat;
}
